#ifndef SES_ADC_H
#define SES_ADC_H

#include <inttypes.h>
#include <avr/io.h>
#include "ses_common.h"



/* sensor ports and pins */
#define ADC_MIC_NEG_PORT        PORTF
#define ADC_MIC_NEG_PIN             0
#define ADC_MIC_POS_PORT        PORTF
#define ADC_MIC_POS_PIN             1
#define ADC_TEMP_PORT           PORTF
#define ADC_TEMP_PIN                2
#define ADC_LIGHT_PORT          PORTF
#define ADC_LIGHT_PIN               4
#define ADC_JOYSTICK_PORT       PORTF
#define ADC_JOYSTICK_PIN            5

#define ADC_CO2_PORT            ADC_LIGHT_PORT   /* optional external sensor */
#define ADC_CO2_PIN             ADC_LIGHT_PIN    /* optional external sensor */

/* reference voltage and prescaling */
#define ADC_VREF_SRC             (1 << REFS1) | (1 << REFS0)  /* use internal 1.6V Voltage Reference */
#define ADC_PRESCALE             (1 << ADPS0) | (1 << ADPS2)  /* ADC clock prescaler 2^(2+4) = 64, clock must be 330kHz or less for 10 bit resolution */

#define CO2_OFFSET_ERR              0  /* offset error correction minuend for ADC*/
#define CO2_GAIN_ERR              2.1  /* gain error correction factor for ADC*/

#define ADMUX_MASK  			  0b11100000



/* setup adc channels */
enum ADChannels{
  ADC_MIC_NEG_CH=0,                     /* ADC0 */
  ADC_MIC_POS_CH,                       /* ADC1 */
  ADC_TEMP_CH,                          /* ADC2 */
  ADC_RESERVED1_CH,                     /* ADC3 */
  ADC_CO2_CH,                           /* ADC4 */
  ADC_JOYSTICK_CH,                      /* ADC5 */
  ADC_RESERVED2_CH,                     /* ADC6 */
  ADC_RESERVED3_CH,                     /* ADC7 */
  ADC_NUM                               /* number of ADC channels*/
};



/**
 * Initialize ports and pins of ADC.
 */
void adc_init(void);

/**
 * Activate power reduction mode, deactivate ADC.
 */
void adc_disable(void);

/**
 * Read sensor value from channel.
 * Called each second.
 *
 * @param adc_channel	enum ADChannels
 *
 * @return raw sensor value
 */
uint16_t adc_read(uint8_t adc_channel);

/**
 * Convert sensor temperature value to degree celsius.
 *
 * @return value in degree celsius
 */
int16_t adc_convertTemp(uint16_t val);

/**
 * Interpolate temperature value between 2 indices.
 *
 * @param index1	lower bound, degree celsius
 * @param index2	upper bound, degree celsius
 * @param value		raw sensor value
 *
 * @returns interpolated value, degree celsius
 */
uint16_t interpolate(uint8_t index1, uint8_t index2, uint16_t value);



#endif /* SES_ADC_H */
